指定した時間にS3 syncでファイルを同期する処理をCloudWatch EventsとCodeBuildでやってみた
こんにちは、臼田です。
みなさん、自動化してますか?(挨拶
今回はすごく具体的な要件ですが指定した時間に自動的にS3 syncする方法についてやってみたので紹介します。
S3 syncを指定した時間に行いたい
まず前提の話ですが、S3 syncはawscliで実行できるコマンドで、指定した送信元S3バケットから宛先S3バケットへファイルを同期する処理が可能です。
よく勘違いされやすいのですが、S3 syncはhigh-level S3 commandsと言われるもので、直接syncするAPIがあるわけではなく、get objectやput objectのAPIを駆使してawscliを実行しているコンピューティングリソース上でコピー作業を実施するラッパーコマンドです。
そのため、例えばLambdaで指定した時間にS3 syncと実行すれば終わりではなく、syncしている間ずっとコンピューティングリソースが動作している必要があります。つまりLambdaだと最大15分までしか動作できないので、対象の量によっては現実的はありません。
というわけで、CloudWatch EventsとCodeBuildで実現する方法を考えました。
ちなみに指定した時間にsyncを行いたい要件としては、毎日決まった時間に同期したい、特定の時間にWebの静的コンテンツをデプロイしたい、等があるかと思います。
S3 syncの方法
ちなみに、単純なS3 syncを行うだけならCodeBuildの他にもLambdaやFargateやAWS Batchもコンピューティングリソースとして利用可能な他、直接的にS3 syncではないですがレプリケーション機能やS3イベントをトリガーにしてLambda等で複製する、S3バッチオペレーションを使うなど色んな方法が考えられます。
CodeBuildを採用するのは大きく下記の理由からです。
- 動作時間の制約がない
- Lambdaは15分まで
- コンテナの用意が不要
- Fargate / AWS Batchは事前にコンテナを用意
- CloudWatch Eventsをトリガーにできる(指定した時間に動作させられる)
- レプリケーションなどはすぐに実行される
もしS3のデータを複製することが目的なら他の方法も検討してみてください。
やってみた
CodeBuildでビルドプロジェクト作成
それでは作っていきます。まずCodeBuildのコンソールへアクセスしてプロジェクトの作成を押します。
プロジェクト名は適当に、ソースプロバイダは今回無いので「ソースがありません」を選択します。
環境ではマネージド型イメージを利用します。個別にDockerイメージを用意しなくていいので便利ですね。OSはAmazon Linux 2にしてランタイムやイメージの詳細は適当に選びます。今回はawscliが動けばいいだけなので、何でもいいです。
サービスロールは新しく作成します。ロール名は自動的に入力されていたのでそれを利用します。この場で権限の設定は行いません。後ほど個別に行います。
処理する内容は1行のawscliなので、ビルドコマンドに直接書いてしまいます。今回はaws s3 sync s3://copy-test-a s3://copy-test-b
としています。アーティファクトも必要ないのでなしです。
ログ出力については今回外しましたが、実運用する際には問題があった時に辿れないと困るのでCloudWatchかS3に出しておきましょう。ビルドプロジェクトを作成します。
作成したら、後ほど使うビルドプロジェクトのARNを控えます。作成したビルドプロジェクトの詳細画面から「ビルドの詳細」タブへ行きプロジェクトARNを控えます。
CodeBuildの準備は完了です。
IAM Roleの権限追加
先程作成されたCodeBuild用のサービスロールにS3 syncを行う権限を追加します。まずはIAMのコンソールへ行き、作成したロールの詳細画面に移動します。移動したらアクセス権限タブから「ポリシーをアタッチします」で任意のポリシーをアタッチします。
今回は簡単に行うためマネージドポリシーのS3FullAccess
を選択しましたが、対象のS3バケットやAPIを制限したほうがいいです。
この設定が完了すればCodeBuildのビルドプロジェクトを開始してS3 syncを実行できます。CloudWatch Eventsの設定前に一度動作確認してみてもいいかもしれません。
CloudWatch Eventsの設定
最後にイベントを設定していきます。
CloudWatch Eventsのルールを作成します。イベントソースにはスケジュールでCron式を入力します。ここで使うCron式はLinuxで設定するものとちょっと違うので注意。あとGMTなので注意。入力すると次回実行時間が出るのでこれを確認しましょう。
ターゲット側ではCodeBuildプロジェクトを選択して、先程のARNを入力します。CloudWatch Eventsが利用するIAM Roleについては画面に表示されているまま作成すれば、実行権限をうまくつけてくれます。
ルールの名前を適当にいれて作成します。
これで完了です。実行されたらビルド履歴から確認できます。
S3の状態を確認してみてください。
まとめ
コンピューティングリソースを管理せず、コンテナイメージを作らないで指定した時間にS3 syncを実行してみました。
ちょっとひと手間かけましたが特定のコンピューティングリソースに縛られない処理なので便利に利用できると思います。
料金的にもデフォルトのイメージでは東京リージョンで0.005USDで、無料枠もあるので非常に良心的だと思います。
やってみてはいかがでしょうか?